/*User program on Nachos
  For project 4
*/

/*Author: Yuzhe Wu 4/14*/
#include "create.h"

struct examSheet examSheetPipe[MAXPATIENTNUM];
struct examSheet wrnExamSheetList[MAXPATIENTNUM];
struct examSheet myLocalExamSheet;
struct examSheet testExamSheet;

void main() {
	int i = 0;
	
	int wrnExamSheetListNum = MAXPATIENTNUM;
	int wrnExamSheetFirstItem = 0;
	int wrnExamSheetLastItem = -1;
	int j=0;
	int test1=0;
	int test2=0;

	int patientListNum = 0;
	bool debugFlag = true;
	
	int waitingRoomNurseCounterValue = 0;
	int waitingRoomPatientCounterValue = 0;
	
	Printf("P4DEBUG: I am wrn, in!\n");
	doCreate();
	
	myLocalExamSheet.patientID=8;
	myLocalExamSheet.name="wqs";
	myLocalExamSheet.age=18;
	myLocalExamSheet.symptom="fever";
	myLocalExamSheet.needShot=true;
	myLocalExamSheet.needXray=false;
	myLocalExamSheet.imageNum=2;
	myLocalExamSheet.xrayResult=3;
	myLocalExamSheet.nextDestination=1;	
	myLocalExamSheet.status=5;
	
	j=rpcCreateMV("test",sizeof("test"),10,0);	
	rpcSetExamSheet(j,myLocalExamSheet);
	test1=rpcGetValueMV(j,0);
	test2=rpcGetValueMV(j,2);
	Printf("the test value is %d and %d \n",test1,test2);
	
	rpcGetExamSheet(j,&testExamSheet);
	Printf("my age is %d\n",testExamSheet.age);
	Printf("my transfer reusulit is patient ID %d,name %s, age %d, symptom %s, needShot %d, needXray %d, imageNum %d\n",testExamSheet.patientID,testExamSheet.name,testExamSheet.age,testExamSheet.symptom,testExamSheet.needShot,testExamSheet.needXray,testExamSheet.imageNum);
	
 	
	if(debugFlag == true) {
		Printf("myDEBUG: Enter waitingRoomNurse threads.\n");
	}
	
	while(1){
		rpcAcquireLock(waitingRoomLock);
		
	
		if((waitingRoomNurseCounterValue=rpcGetValueMV(waitingRoomNurseCounter,0))>0) { /*A nurse is in line*/
			rpcSignalCV(waitingRoomLock, nurseWaitingWRCV);
			rpcSetValueMV(waitingRoomNurseCounter,0,waitingRoomNurseCounterValue-1);
			rpcSetValueMV(wrnState,0,BUSY);
		}
		
		
		else if((waitingRoomPatientCounterValue=rpcGetValueMV(waitingRoomPatientCounter,0))>0) { /*A patient is in line*/
			rpcSignalCV(waitingRoomLock, patientWaitingWRCV);
			rpcSetValueMV(waitingRoomPatientCounter,0,waitingRoomPatientCounterValue-1);
			rpcSetValueMV(wrnState,0,BUSY);		
		}
		
		else {
			rpcSetValueMV(wrnState,0,FREE);	
		}
		
		rpcAcquireLock(wrnLock);
		rpcReleaseLock(waitingRoomLock);
		
		if(debugFlag == true) {
			Printf("myDEBUG: wrn Start to wait!\n");
		} 
		
		rpcWaitCV(wrnLock,wrnPatient_NurseCV);
		
		if(debugFlag == true) {
			Printf("myDEBUG: WRN is signal by patient or nurse!\n");
		} 
	
/*Interaction with Patient or Nurse*/
		/*Check the three possible tasks: GETFORM GIVEFORM CALLPATIENT*/
		
		if(rpcGetValueMV(wrnTask,0) == GETFORM ){
			Printf("Waiting Room nurse gives a form to Adult patient [%d]\n",rpcGetValueMV(patientIDTONurse,0));
			rpcSetExamSheet(wrnExamSheetEmpty,examSheetPipe[patientListNum]);
			patientListNum ++ ;
			rpcSignalCV(wrnLock, wrnPatient_NurseCV);
			
			if(debugFlag == true) {
				Printf("myDEBUG: WRN is ready to wait!\n");
			}
			
			rpcWaitCV(wrnLock,wrnPatient_NurseCV);
			if(debugFlag == true) {
				Printf("myDEBUG:WRN has given the examSheet to a patient.\n");
			}
		}

		else if(rpcGetValueMV(wrnTask,0) == GIVEFORM){
			/*Append*/
			wrnExamSheetLastItem++;
			if(wrnExamSheetLastItem==wrnExamSheetListNum){
				wrnExamSheetLastItem = 0;
			}
			
			rpcGetExamSheet(wrnExamSheet, &wrnExamSheetList[wrnExamSheetLastItem]);
			if(debugFlag == true) {
				Printf("myDebug: the index of wrnExamSheet is %d. the wrnExamSheetLastItem is %d\n",wrnExamSheet,wrnExamSheetLastItem);
				Printf("myDEBUG:WaitingRoomNurse append           %d              patient in list\n\n\n\n", wrnExamSheetList[wrnExamSheetLastItem].patientID);
			}
			
			rpcSignalCV(wrnLock, wrnPatient_NurseCV);
			rpcWaitCV(wrnLock, wrnPatient_NurseCV);
			
			rpcGetExamSheet(wrnExamSheet, &myLocalExamSheet);
			if(debugFlag == true) {
				Printf("myDEBUG:WRN has put the a examSheet to a list.\n");
			}
			Printf("Waiting Room nurse accepts the form from Adult Patient/Parent with name [%s] and age [%d]\n", myLocalExamSheet.name, myLocalExamSheet.age);
			Printf("Waiting Room nurse creates an examination sheet for [Adult/Child] patient with name [%s] and age [%d]\n", myLocalExamSheet.name, myLocalExamSheet.age);
			Printf("Waiting Room nurse tells the Adult Patient/Parent [%s] to wait in the waiting room for a nurse\n", myLocalExamSheet.name);	
		}		
		
		else if (rpcGetValueMV(wrnTask,0) == CALLPATIENT){
			rpcSignalCV(wrnLock, wrnPatient_NurseCV);
			rpcWaitCV(wrnLock,wrnPatient_NurseCV);
			
			/*Remove*/
			rpcSetExamSheet(wrnExamSheet, wrnExamSheetList[wrnExamSheetFirstItem]);

			
			if(debugFlag == true) {
				Printf("myDEBUG:WaitingRoomNurse remove           %d              patient in list\n\n\n",wrnExamSheetList[wrnExamSheetFirstItem].patientID);
			}
			
			Printf("Waiting Room nurse gives examination sheet to patient[%s] to Nurse [%d].\n",wrnExamSheetList[wrnExamSheetFirstItem].patientID,rpcGetValueMV(nurseIDTOWRN,0));
			wrnExamSheetFirstItem++;
			if(wrnExamSheetFirstItem == wrnExamSheetListNum) {
				wrnExamSheetFirstItem =0;
			}
			
			rpcSignalCV(wrnLock, wrnPatient_NurseCV);
			rpcWaitCV(wrnLock,wrnPatient_NurseCV);		
		}
		
		else{
			Printf("ERROR:WRONG WrnTask.\n");
		}
		
		rpcReleaseLock(wrnLock);
	/*	 rpcAcquireLock(patientLeftNumLock);
		
		if(rpcGetValueMV(patientLeftNum,0) == rpcGetValueMV(patientNum,0)) {
			Exit(0);
		}
		rpcReleaseLock(patientLeftNumLock);
	*/
	}
}